#!/bin/bash
# 该运维脚本如有功能更新，需同步更新效能运维文档，并知会运维同学
version="v1.1.0 20240628 performance tool for k3s deployment"
namespace=ones

getLocalstorageStorageBasePath() {
    kubectlInstallerCmd="kubectl -n ones-installer exec deploy/installer-api -c installer-api -- "
    localstorageStorageBasePath=$(${kubectlInstallerCmd} make get_value KEY=localstorageStorageBasePath)
    if [ "$localstorageStorageBasePath" = "" ]; then
      echo "[ERROR] get localstorageStorageBasePath empty! "
      exit 1
    fi
    echo "${localstorageStorageBasePath}"
}

etlStatus(){
  # 打印当前 etl 服务同步状态
   pod=$(kubectl get po -nones | grep bi-sync-etl | awk '{print $1}')
   kubectl exec -it -nones "${pod}" -- etl/ones-bi-sync-etl -s status -c etl/config.json
}

# 同步完成后强制进行一次数据优化，可避免出现相同数据，通常情况下 etl 服务会在每天凌晨进行一次优化
optimizeCHTable(){
    # 获取连接 Clickhouse 的用户名密码和端口
    kubectlInstallerCmd="kubectl -n ones-installer exec deploy/installer-api -c installer-api -- "
    ckUser=$(${kubectlInstallerCmd} make get_value KEY=clickhouseUser)
    if [ "$ckUser" = "" ]; then
      echo "[ERROR] get clickhouseUser empty! "
      exit 1
    fi
    echo "clickhouseUser: ${ckUser}"

    ckPassWord=$(${kubectlInstallerCmd} make get_value KEY=clickhousePassword)
    if [ "$ckUser" = "" ]; then
      echo "[ERROR] get clickhousePassword empty! "
      exit 1
    fi
    echo "clickhousePassword: ****"

    ckTcpPort=$(${kubectlInstallerCmd} make get_value KEY=clickhousePortTCP)
    if [ "$ckTcpPort" = "" ]; then
      echo "[ERROR] get clickhousePortTCP empty! "
      exit 1
    fi
    echo "clickhousePortTCP: ${ckTcpPort}"

    # 执行优化
    pod=$(kubectl get po -nones | grep clickhouse-statefulset-0 | awk '{print $1}')
    kubectl exec -it -nones "${pod}" -- clickhouse-client -q "OPTIMIZE TABLE default.task FINAL" --port "${ckTcpPort}" --user "${ckUser}" --password "${ckPassWord}"
    echo "OPTIMIZE TABLE default.task FINAL success"
    kubectl exec -it -nones "${pod}" -- clickhouse-client -q "OPTIMIZE TABLE default.field_value_history FINAL" --port "${ckTcpPort}" --user "${ckUser}" --password "${ckPassWord}"
    echo "OPTIMIZE TABLE default.field_value_history FINAL success"
    kubectl exec -it -nones "${pod}" -- clickhouse-client -q "OPTIMIZE TABLE default.manhour FINAL" --port "${ckTcpPort}" --user "${ckUser}" --password "${ckPassWord}"
    echo "OPTIMIZE TABLE default.manhour FINAL success"
}

forceRebuildALLPerformance(){
    echo "---- start to reset all performance data..."
    sleep 1
    set -e
    kubectlInstallerCmd="kubectl -n ones-installer exec deploy/installer-api -c installer-api -- "
    # 0 获取用于重建的 kafka 连接方式/topic 名称/目录存储路径
    localstorageStorageBasePath=$(getLocalstorageStorageBasePath)
    echo "localstorageStorageBasePath: ${localstorageStorageBasePath}"

    KafkaReadAddress=$(${kubectlInstallerCmd} make get_value KEY=KafkaReadAddress)
    if [ "$KafkaReadAddress" = "" ]; then
      echo "[ERROR] get KafkaReadAddress empty! "
      exit 1
    fi
    echo "KafkaReadAddress: ${KafkaReadAddress}"

    performanceTopicName=$(${kubectlInstallerCmd} make get_value KEY=kafkaProjectBinlogTopic)
    if [ "$performanceTopicName" = "" ]; then
      echo "[ERROR] get kafkaProjectBinlogTopic empty! "
      exit 1
    fi
    echo "kafkaProjectBinlogTopic: ${performanceTopicName}
    "

    # 1.将副本数降为 0，停止效能管道同步服务
    echo "---- step 1 stop bi-sync-*-deployment:"
    deploymentScaleCmd="kubectl -n ones scale deployment ones-bi-sync-canal-deployment ones-bi-sync-etl-deployment --replicas="
    replicas=0
    stopDeploymentCmd="${deploymentScaleCmd}${replicas}"
    echo "${stopDeploymentCmd}"
    if ! $stopDeploymentCmd; then
        echo "[ERROR] stop bi-sync-*-deployment failed !"
        exit 1
    fi
    echo ""

    # 2. 删除kafka 中效能的 topic（bi-sync-etl 服务启动时会重新创建topic）
    echo "---- step 2 delete topic ${performanceTopicName}:"
    pod=$(kubectl get po -nones | grep kafka-ha-0 | awk '{print $1}')
    delTopicCmd="kubectl exec -it -nones ${pod} -- kafka-topics.sh --bootstrap-server ${KafkaReadAddress} --delete --topic ${performanceTopicName}"
    echo "${delTopicCmd}
    "
    ret=$($delTopicCmd)
    if [ "$ret" != "" ]; then
        retGroup="$(echo "${ret}" | grep "does not exist as expected")" # topic 不存在，认为删除 topic 成功
        if [ "${retGroup}" = "" ]; then
          echo "[ERROR] delete topic ${performanceTopicName} failed !
          "
          exit 1
        fi
    fi

    # 3. 删除 bolt 偏移文件
    echo "---- step 3 delete ones-bi-sync-*/* files:"
    delBoltFilesCmd="rm -rf ${localstorageStorageBasePath}/others-static-pvc/${namespace}/ones-bi-sync-*/*bolt"
    echo "${delBoltFilesCmd}
    "
    if ! $delBoltFilesCmd; then
        echo "[ERROR] delete bolt files failed !"
        exit 1
    fi

    # 4.将副本数改为 1，启动服务 pod
    echo "---- step 4 redeploy bi-sync-*-deployment"
    replicas=1
    startDeploymentCmd="${deploymentScaleCmd}${replicas}"
    echo "${startDeploymentCmd}"
    if ! $startDeploymentCmd; then
        echo "[ERROR] start bi-sync-*-deployment failed !"
        exit 1
    fi
}

forceRebuildALLPerformanceCDC(){
    echo "---- start to reset all cdc performance data ..."
    sleep 1
    set -e

    # 0 获取用于重建的 kafka 连接方式/topic 名称/目录存储路径
    localstorageStorageBasePath=$(getLocalstorageStorageBasePath)
    echo "localstorageStorageBasePath: ${localstorageStorageBasePath}"

    # 1.将副本数降为 0，停止效能管道同步服务
    echo "---- step 1 stop bi-sync-etl-deployment:"
    deploymentScaleCmd="kubectl -n ones scale deployment ones-bi-sync-etl-deployment --replicas="
    replicas=0
    stopDeploymentCmd="${deploymentScaleCmd}${replicas}"
    echo "${stopDeploymentCmd}"
    if ! $stopDeploymentCmd; then
        echo "[ERROR] stop bi-sync-etl-deployment failed !"
        exit 1
    fi
    sleep 2
    echo ""

    # 2. 删除 bolt 偏移文件
    echo "---- step 2 delete ones-bi-sync-*/* files:"
    delBoltFilesCmd="rm -rf ${localstorageStorageBasePath}/others-static-pvc/${namespace}/ones-bi-sync-*/*bolt"
    echo "${delBoltFilesCmd}
    "
    if ! $delBoltFilesCmd; then
        echo "[ERROR] delete bolt files failed !"
        exit 1
    fi

    # 3.设置 cdc 的 etl 配置为全部强制重建
    echo "---- step 3 set onesBISyncEtlForceSnapshot* and make setup-ones"
    ret=$(kubectl -n ones-installer exec deploy/installer-api -c installer-api -- bash -c "
    grep -vE onesBISyncEtl.*Snapshot config/private.yaml > config/private_rebuild_performance.yaml
    echo  'onesBISyncEtlForceSnapshotAll: true' >> config/private_rebuild_performance.yaml
    echo  'onesBISyncEtlForceSnapshotVersion: $(date +'%Y%m%d%H%M%S')' >> config/private_rebuild_performance.yaml
    mv config/private_rebuild_performance.yaml config/private.yaml;tail -2 config/private.yaml
    make setup-ones")

    # shellcheck disable=SC2181
    if [ $? -ne 0 ]; then
        echo "[ERROR] ${ret}
        "
        exit 1
    else
       echo "---- set config/private.yaml success: "
       echo "${ret}" | grep "onesBISyncEtl"
       echo ""
    fi

    # 4.将副本数改为 1，启动服务 pod
    echo "---- step 4 redeploy ones-bi-sync-etl-deployment"
    replicas=1
    startDeploymentCmd="${deploymentScaleCmd}${replicas}"
    echo "${startDeploymentCmd}"
    if ! $startDeploymentCmd; then
        echo "[ERROR] start ones-bi-sync-etl-deployment failed !"
        exit 1
    fi
}

quickRebuildALLPerformanceCDC(){
    echo "---- start to reset cdc performance data by the specified tables quickly ..."
    sleep 1
    set -e

    # 将副本数降为 0，停止效能管道同步服务
    echo "---- step 1 stop bi-sync-etl-deployment:"
    deploymentScaleCmd="kubectl -n ones scale deployment ones-bi-sync-etl-deployment --replicas="
    replicas=0
    stopDeploymentCmd="${deploymentScaleCmd}${replicas}"
    echo "${stopDeploymentCmd}"
    if ! $stopDeploymentCmd; then
        echo "[ERROR] stop bi-sync-etl-deployment failed !"
        exit 1
    fi
    sleep 2
    echo ""

    # 设置 cdc 的 etl 配置为快速重建
    echo "---- step 2 set onesBISyncEtlQuickSnapshot* and make setup-ones"
    ret=$(kubectl -n ones-installer exec deploy/installer-api -c installer-api -- bash -c "
    grep -vE onesBISyncEtl.*Snapshot config/private.yaml > config/private_rebuild_performance.yaml
    echo  'onesBISyncEtlQuickSnapshotTables: $2' >> config/private_rebuild_performance.yaml
    echo  'onesBISyncEtlQuickSnapshotVersion: $(date +'%Y%m%d%H%M%S')' >> config/private_rebuild_performance.yaml
    mv config/private_rebuild_performance.yaml config/private.yaml;tail -2 config/private.yaml
    make setup-ones")

    # shellcheck disable=SC2181
    if [ $? -ne 0 ]; then
        echo "[ERROR] ${ret}
        "
        exit 1
    else
       echo "---- set config/private.yaml success: "
       echo "${ret}" | grep "onesBISyncEtl"
       echo ""
    fi

    # 将副本数改为 1，启动服务 pod
    echo "---- step 3 redeploy ones-bi-sync-etl-deployment"
    replicas=1
    startDeploymentCmd="${deploymentScaleCmd}${replicas}"
    echo "${startDeploymentCmd}"
    if ! $startDeploymentCmd; then
        echo "[ERROR] start ones-bi-sync-etl-deployment failed !"
        exit 1
    fi
   echo ""
   echo "---- wait a few seconds for restart ...
   "
   sleep 8
   echo "---- reset performance success ----"
}

argv=$1
# 判断当前环境是否存在 kafka-cdc-connect pod，若不存在则为旧环境
kafkaCdcConnect=$(kubectl get po -nones | grep kafka-cdc-connect | awk '{print $1}')
if [ "$argv" = "-a" ]; then
   if [ "$kafkaCdcConnect" != "" ]; then
       forceRebuildALLPerformanceCDC
   else
       forceRebuildALLPerformance # （兼容旧版）将删除  bi-sync-canal 和 etl 以及 kafka 的效能数据
   fi
   echo ""
   echo "---- wait a few seconds for restart ...
   "
   sleep 8
   echo "---- reset performance success ----"
elif [ "$argv" = "-q" ]; then
  if [ "$2" = "" ]; then
      echo "[ERROR] please specify db:table for rebuild"
      exit 1
  fi
  quickRebuildALLPerformanceCDC "$@"
elif [ "$argv" = "-s" ]; then
   etlStatus
elif [ "$argv" = "-o" ]; then
   optimizeCHTable
elif [ "$argv" = "-v" ]; then
   echo "${version}"
else
   if [ "$kafkaCdcConnect" != "" ]; then
      echo "usage:
    [-a]: Reset the performance data, include ones-bi-sync-etl/clickhouse performance data with kafka cdc snapshots.
    [-q]: Reset the performance data quickly by the specified tables. eg [-q project:task,project:sprint]"
   else
      echo "usage:
    [-a]: Reset all performance data, include ones-bi-sync-canal/ones-bi-sync-etl/kafka && clickhouse performance data."
   fi
    echo "    [-s]: Show bi-sync-etl sync status.
    [-o]: Optimize tables (task, field_value_history, manhour), to avoid the same data.
    [-v]: Show version."
fi